import { _decorator, Node, UITransform, Vec2 } from 'cc'
import { EntityManager } from '../../Base/EntityManager'
import { IActor, InputTypeEnum, toFixed } from '../../Common'
import { EntityStateEnum, EventEnum } from '../../Enum'
import DataManager from '../../Global/DataManager'
import EventManager from '../../Global/EventManager'
import { WeaponStateMachine } from './WeaponStateMachine'
const { ccclass } = _decorator

// 武器控制模块
@ccclass('WeaponManager')
export class WeaponManager extends EntityManager {
  // 拥有者id
  owner: number
  // 武器主体
  private body: Node
  // 子弹坐标锚
  private anchor: Node
  // 子弹
  private point: Node

  init(data: IActor) {
    // 获取武器节点
    this.owner = data.id
    this.body = this.node.getChildByName('Body')
    this.anchor = this.body.getChildByName('Anchor')
    this.point = this.anchor.getChildByName('Point')

    // 绑定有限状态机
    this.fsm = this.body.addComponent(WeaponStateMachine)
    // 初始化状态机
    this.fsm.init(data.weaponType)
    // 初始化武器状态
    this.state = EntityStateEnum.Idle

    // 绑定射击事件
    EventManager.Instance.on(EventEnum.WeaponShoot, this.handleWeaponShoot, this)
    // 绑定开枪爆炸
    EventManager.Instance.on(EventEnum.BulletBorn, this.handleBulletBorn, this)
  }

  onDestroy() {
    EventManager.Instance.off(EventEnum.WeaponShoot, this.handleWeaponShoot, this)
    EventManager.Instance.off(EventEnum.BulletBorn, this.handleBulletBorn, this)
  }
  // 处理射击动作
  handleWeaponShoot() {
    // 非武器主人不触发
    if (this.owner !== DataManager.Instance.playerID) return
    // 死亡失去射击能力
    if (DataManager.Instance.actorMap.get(this.owner).isDead) return

    // 子弹的世界坐标
    const pointWorldPos = this.point.getWorldPosition()
    // 将世界坐标转换为舞台下的相对坐标
    const pointStagePos = DataManager.Instance.stage.getComponent(UITransform).convertToNodeSpaceAR(pointWorldPos)
    const anchorWorldPos = this.anchor.getWorldPosition()
    Vec2.subtract(pointWorldPos, pointWorldPos, anchorWorldPos)
    // 向事件中心触发射击帧同步
    EventManager.Instance.emit(EventEnum.ClientSync, {
      owner: this.owner,
      type: InputTypeEnum.WeaponShoot,
      position: { x: toFixed(pointStagePos.x), y: toFixed(pointStagePos.y) },
      direction: { x: toFixed(pointWorldPos.normalize().x), y: toFixed(pointWorldPos.normalize().y) },
    })
  }

  // 处理开枪爆炸
  handleBulletBorn(owner: number) {
    if (owner !== this.owner) return
    this.state = EntityStateEnum.Attack
  }
}
